package com.inool.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.inool.common.exception.InoolException;
import com.inool.common.result.Result;
import com.inool.mapper.CourseMapper;
import com.inool.mapper.CourseScheduleMapper;
import com.inool.mapper.GradeMapper;
import com.inool.mapper.StudentMapper;
import com.inool.mapper.TeacherMapper;
import com.inool.model.Course;
import com.inool.model.CourseSchedule;
import com.inool.model.Grade;
import com.inool.model.dto.CourseScheduleDto;
import com.inool.model.dto.StudentDto;
import com.inool.service.CourseScheduleService;
import com.inool.vo.ConfrimCourseRequestVO;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleMapper, CourseSchedule> implements CourseScheduleService {


    @Autowired
    private CourseScheduleMapper courseScheduleMapper;

    @Autowired
    private GradeMapper gradeMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private TeacherMapper teacherMapper;

    @Override
    public CourseSchedule addCourseSchedule(CourseSchedule courseSchedule) {
        save(courseSchedule);
        return courseSchedule;
    }

    @Override
    public List<CourseSchedule> getAllCourseSchedules() {
        List<CourseSchedule> courseSchedules = list();
        for (CourseSchedule courseSchedule : courseSchedules) 
        {
            courseSchedule.setTeacher(teacherMapper.selectById(courseSchedule.getStaffNumber()));
            courseSchedule.setCourse(courseMapper.selectById(courseSchedule.getCourseId()));
            courseSchedule.setEnrolledStudents(getEnrolledStudents(courseSchedule.getId()));
        }   
        return courseSchedules;
    }
    @Override
    public Result<String> openCourse(String courseId, String staffNumber) {
        CourseSchedule courseSchedule = new CourseSchedule();
        courseSchedule.setCourseId(courseId);
        courseSchedule.setStaffNumber(staffNumber);
        
        // 假设使用 MyBatis-Plus 的 save 方法插入课程调度记录
        boolean success = courseScheduleMapper.insert(courseSchedule) > 0;
        if (success) {
            return Result.ok("课程开设成功");
        } else {
            return Result.fail("课程开设失败");
        }
    }

    @Override
    public Result<String> confirmCourse(ConfrimCourseRequestVO confrimCourseRequestVO) {
        // 获取课程调度记录
       

        // 检查选课人数
        // int enrolledStudents = getEnrolledStudents(confrimCourseRequestVO.getId());
        // int minEnrollment = getCapacity(confrimCourseRequestVO.getId())/2;
        // if (enrolledStudents < minEnrollment) {
        //     return Result.fail("选课人数不足，课程不开设");
        // }

        
        CourseSchedule courseSchedule = courseScheduleMapper.selectById(confrimCourseRequestVO.getId());
        
        // 设置课程时间
        courseSchedule.setId(confrimCourseRequestVO.getId());
        courseSchedule.setScheduleInfo(confrimCourseRequestVO.getScheduleInfo());
        courseSchedule.setCapacity(confrimCourseRequestVO.getCapacity());
        courseSchedule.setStaffNumber(confrimCourseRequestVO.getStaffNumber());
        courseSchedule.setCourseId(confrimCourseRequestVO.getCourseId());
        
        boolean success = updateById(courseSchedule);
        if (success) {
            return Result.ok("课程正式开设成功");
        } else {
            return Result.fail("课程正式开设失败");
        }
    }

    public int getCapacity(Long courseScheduleId) {
       return Optional.ofNullable(getById(courseScheduleId))
       // 使用 Lambda 表达式替代方法引用
       .map(courseSchedule -> courseSchedule.getCapacity()) 
       .orElse(0);
    }
    public int getEnrolledStudents(Long courseScheduleId) {
        // 使用 LambdaQueryWrapper 构建查询条件
        LambdaQueryWrapper<Grade> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Grade::getCourseScheduleId, courseScheduleId);
        // 调用 count 方法统计符合条件的记录数
        return (int) gradeMapper.selectCount(queryWrapper);
    }

    @Override
    public String selectCourse(Long courseScheduleId, String studentId) {
        // 检查课程是否存在
        CourseSchedule courseSchedule = courseScheduleMapper.selectById(courseScheduleId.intValue());
        if (courseSchedule == null) {
            return "课程不存在";
       
        }
        // 检查学生是否已经选择了该课程
        LambdaQueryWrapper<Grade> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Grade::getCourseScheduleId, courseScheduleId)
        .eq(Grade::getStudentNumber, studentId);
        int count = gradeMapper.selectCount(queryWrapper);
        if (count>0) {
            return "您已经选择了该课程";
        } 
        else {
            // 检查课程是否已经满员
            if (getCapacity(courseScheduleId) <= getEnrolledStudents(courseScheduleId)) {
                return "课程已满"; 
            }
         }
        Grade grade = new Grade();
        grade.setCourseScheduleId(courseScheduleId);
        grade.setStudentNumber(studentId);
        gradeMapper.insert(grade);
        return "选课成功";
    }

    
     @Override
    public List<CourseScheduleDto> getCoursesByStaffNumber(String staffNumber) {
        // 首先查询课程安排信息
        LambdaQueryWrapper<CourseSchedule> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CourseSchedule::getStaffNumber, staffNumber);
        List<CourseSchedule> courseSchedules = courseScheduleMapper.selectList(queryWrapper);
        
        // 将 CourseSchedule 转换为 CourseScheduleDto 并填充学生信息
        return courseSchedules.stream()
               .map(courseSchedule -> {
                    CourseScheduleDto courseScheduleDto = new CourseScheduleDto();
                    // 复制课程安排的属性到 DTO
                    courseScheduleDto.setId(courseSchedule.getId());
                    courseScheduleDto.setScheduleInfo(courseSchedule.getScheduleInfo());
                    courseScheduleDto.setCourseId(courseSchedule.getCourseId());
                    courseScheduleDto.setStaffNumber(courseSchedule.getStaffNumber());
                    courseScheduleDto.setCapacity(courseSchedule.getCapacity());
                    courseScheduleDto.setEnrolledStudents(courseSchedule.getEnrolledStudents());
                    courseScheduleDto.setTeacher(courseSchedule.getTeacher());
                    Course course = courseMapper.selectById(courseSchedule.getCourseId());
                    courseScheduleDto.setCourse(course);

                    // 假设这里有一个方法获取对应课程的学生列表
                    //List<Student> students = studentMapper.getStudentsByCourseScheduleId(courseSchedule.getId());

                    List<StudentDto> students = studentMapper.getStudentsWithGradesByCourseScheduleId(courseSchedule.getId());                    
                    courseScheduleDto.setStudents(students);
                    courseScheduleDto.setEnrolledStudents(Integer.valueOf(students.size()));
                    return courseScheduleDto;
                })
               .collect(Collectors.toList());
    }

     @Override
     public Boolean removeCourse(Long courseScheduleId) {
        return removeById(courseScheduleId);
     }

     @Override
     public List<CourseSchedule> getSelectedCourses(String studentNumber) {
        // 首先查询课程安排信息        
        
        List<CourseSchedule> courseSchedules = courseScheduleMapper.queryStudentSelectedCourses(studentNumber);
        for (CourseSchedule courseSchedule : courseSchedules) {
            courseSchedule.setTeacher(teacherMapper.selectById(courseSchedule.getStaffNumber()));
            courseSchedule.setCourse(courseMapper.selectById(courseSchedule.getCourseId())); 
        }
        return courseSchedules;
     }

     @Override
     public Boolean cancelCourse(Long courseScheduleId, String studentNumber) {
        //查询该生该门课程是否不为空
        LambdaQueryWrapper<Grade> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Grade::getCourseScheduleId, courseScheduleId)
        .eq(Grade::getStudentNumber, studentNumber);
        Grade grade = gradeMapper.selectOne(queryWrapper);
        if(grade.getScore()!=null){
            throw new InoolException(230,"已参加考试的课程不能退课");
        }
        return gradeMapper.delete(queryWrapper)>0;


     }
    
}    